package installer

import (
	"fmt"
	"os/exec"

	"go.uber.org/zap"
)

// checkDependencies 检查编译依赖
// 示例值: 无参数
func (i *Installer) checkDependencies() error {
	zap.L().Info("检查编译依赖")

	// 检查必要的编译工具
	dependencies := []string{
		"gcc", "make", "autoconf", "automake", "libtool",
		"zlib1g-dev", "libssl-dev", "libpam0g-dev",
	}

	// 创建统一的包管理器
	pm, err := NewPackageManager()
	if err != nil {
		zap.L().Error("创建包管理器失败", zap.Error(err))
		// 如果包管理器创建失败，回退到原来的检测方式
		return i.fallbackCheckDependencies(dependencies)
	}

	// 使用统一的包管理器检测依赖
	for _, dep := range dependencies {
		// 获取对应系统的包名
		packageName := pm.GetPackageMapping(dep)
		
		if !pm.IsPackageInstalled(packageName) {
			zap.L().Warn("依赖包未安装", 
				zap.String("package", dep), 
				zap.String("system_package", packageName))
			
			// 如果包未安装，尝试自动安装
			zap.L().Info("尝试自动安装依赖包", 
				zap.String("package", dep), 
				zap.String("system_package", packageName))
			
			if !pm.InstallPackage(packageName) {
				zap.L().Error("无法安装依赖包", 
					zap.String("package", dep), 
					zap.String("system_package", packageName))
				
				// 安装失败，回退到备用检测方式
				if !i.checkCommandExists(dep) {
					return fmt.Errorf("缺少依赖且无法自动安装: %s (系统包名: %s)", dep, packageName)
				}
				zap.L().Info("依赖包通过备用方式检测通过", zap.String("package", dep))
			} else {
				zap.L().Info("依赖包安装成功", 
					zap.String("package", dep), 
					zap.String("system_package", packageName))
			}
		} else {
			zap.L().Info("依赖包已安装", 
				zap.String("package", dep), 
				zap.String("system_package", packageName))
		}
	}

	zap.L().Info("所有依赖检查通过")
	return nil
}

// fallbackCheckDependencies 备用依赖检测方式
func (i *Installer) fallbackCheckDependencies(dependencies []string) error {
	zap.L().Warn("使用备用依赖检测方式")
	
	for _, dep := range dependencies {
		if !i.checkCommandExists(dep) {
			return fmt.Errorf("缺少依赖: %s", dep)
		}
	}
	
	zap.L().Info("备用依赖检测通过")
	return nil
}

// checkCommandExists 检查命令是否存在（保留作为备用方案）
// 示例值: command="gcc"
func (i *Installer) checkCommandExists(command string) bool {
	cmd := exec.Command("which", command)
	return cmd.Run() == nil
}